#include <iostream>
#include "GraphFlowList.h"

using namespace std;

GraphFlowList::GraphFlowList() : GraphFlow(), GraphOrientedList() {}

GraphFlowList::GraphFlowList(const GraphFlow &g)
{
  summit_nb = g.getSummitNb();
  edges_nb = g.getEdgesNb();
  info = new vector<Values *>[summit_nb];
  vector<summit_t> * temp;
  Values * v;
  for (summit_t i=0; i<summit_nb; i++)
  {
    temp = g.getNeighbours(i);
    for (size_t j=0; j<temp->size(); j++)
    {
      v = new Values();
      v->neighbour=temp->at(j);
      v->flow=g.getFlow(i,temp->at(j));
      v->capacity=g.getCapacity(i,temp->at(j));
      info[i].push_back(v);
    }
    delete temp;
  }
}

GraphFlowList::GraphFlowList(summit_t n, edges_t m) : GraphFlow(), GraphOrientedList() //Ici on veut un héritage des méthodes seulement
{
  summit_nb = n;
  edges_nb = m;

  info = new vector<Values *>[summit_nb];
}

GraphFlowList::~GraphFlowList()
{
  for (summit_t i=0; i<summit_nb; i++)
  {
    for (size_t j=0; j<info[i].size(); j++)
    {
      delete info[i][j];
    }
  }
  delete [] info;
}

const vector<Values *>& GraphFlowList::getValues(summit_t i) const
{
  return info[i];
}

flow_t GraphFlowList::getFlow(summit_t i, summit_t j) const
{
  for (size_t k=0; k<info[i].size(); k++)
  {
    if (info[i][k]->neighbour == j)
      return info[i][k]->flow;
  }
  return 0;
}

flow_t GraphFlowList::getCapacity(summit_t i, summit_t j) const
{
    for (size_t k=0; k<info[i].size(); k++)
  {
    if (info[i][k]->neighbour == j)
      return info[i][k]->capacity;
  }
  return 0;
}

void GraphFlowList::setFlow(summit_t i, summit_t j, flow_t f)
{
  for (size_t k=0; k<info[i].size(); k++)
  {
    if (info[i][k]->neighbour == j)
    {
      info[i][k]->flow = f;
      return;
    }
  }
}

void GraphFlowList::setCapacity(summit_t i, summit_t j, flow_t f)
{
  for (size_t k=0; k<info[i].size(); k++)
  {
    if (info[i][k]->neighbour == j)
    {
      info[i][k]->capacity = f;
      return;
    }
  }
}

// Redéfinition des méthodes de GraphOrientedList
bool GraphFlowList::areConnected(summit_t i, summit_t j) const
{
  for (size_t k=0; k<info[i].size(); k++)
  {
    if (info[i][k]->neighbour == j)
      return true;
  }
  return false;
}

void GraphFlowList::connect(summit_t i, summit_t j)
{
    info[i].push_back(new Values);
    info[i][info[i].size()-1]->neighbour = j;
}

void GraphFlowList::deconnect(summit_t i, summit_t j)
{
  if (areConnected(i,j))
  {
    for (size_t k=0; k<info[i].size(); k++)
    {
      if (info[i][k]->neighbour == j)
      {
	delete info[i][k];
	info[i].erase(info[i].begin()+k);
	return;
      }
    }
  }
}

